﻿using DevComponents.DotNetBar.Controls;
using DevComponents.DotNetBar.SuperGrid;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Controls;
using ESRI.ArcGIS.Display;
using ESRI.ArcGIS.Geometry;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using PlanningGIS.ArcGIS;
using PlanningGIS.MapSheet;
using PlanningGIS.Util.Log;
using PlanningGIS.Win.Controls;

namespace PlanningGIS.Framework.Controls
{
    /// <summary>
    /// 图幅构建类
    /// </summary>
    public class SheetCreator
    {
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="grid">图幅列表</param>
        /// <param name="hasName">是否显示图幅名称列，默认显示</param>
        public SheetCreator(SuperGridControl grid, bool hasName = true)
        {
            _SuperGrid = grid;
            _HasName = hasName;
            InitControl();
            _UserCreator = new UserMapsheet();
        }

        /// <summary>
        /// 列表对象
        /// </summary>
        private SuperGridControl _SuperGrid = null;

        /// <summary>
        /// 图幅名称前缀
        /// </summary>
        private string _ElementName = "_Sheet";

        /// <summary>
        /// 是否显示图幅名称列，默认显示
        /// </summary>
        private bool _HasName = true;

        /// <summary>
        /// 地图关联对象
        /// </summary>
        private IHookHelper _HookHelper = null;

        /// <summary>
        /// 地图关联对象
        /// </summary>
        public object Hook
        {
            set
            {
                try
                {
                    _HookHelper = new HookHelper();
                    _HookHelper.Hook = value;
                }
                catch
                {
                    _HookHelper = null;
                }
            }
        }

        /// <summary>
        /// 获取或设置是否将选中的对象添加到地图中
        /// </summary>
        public bool IsToMap { get; set; }

        /// <summary>
        /// 当期的比例尺
        /// </summary>
        private double _ScaleValue = 500;

        /// <summary>
        /// 当期的比例尺
        /// </summary>
        public double ScaleValue
        {
            get { return _ScaleValue; }
            set
            {
                _ScaleValue = value;
                _UserCreator.Scale = value;
            }
        }

        /// <summary>
        /// 获取选中的图幅
        /// </summary>
        public Mapsheet SeletedSheet
        {
            get
            {
                if (_SuperGrid.PrimaryGrid.Rows.Count == 0) return null;
                if (_SuperGrid.PrimaryGrid.SelectedRowCount == 0) return null;
                if (_SuperGrid.PrimaryGrid.ActiveRow == null) return null;
                GridRow r = (GridRow)(_SuperGrid.PrimaryGrid.ActiveRow);
                Mapsheet st = (Mapsheet)r.Tag;
                if (_HasName) st.Name = r.Cells[2].Value == null ? "" : r.Cells[2].Value.ToString();
                return st;
            }
        }

        /// <summary>
        /// 绘制到地图中的对象
        /// </summary>
        public List<IElement> Elements { get; private set; }

        /// <summary>
        /// 获取列表中所有的图幅项
        /// </summary>
        public List<Mapsheet> AllSheets { get; protected set; }

        /// <summary>
        /// 获取列表中所有选中的图幅
        /// </summary>
        public List<Mapsheet> CheckedSheets
        {
            get
            {
                if (AllSheets == null || AllSheets.Count == 0) return null;
                return AllSheets.FindAll(t => t.Checked);
            }
        }

        #region 自定义图幅相关
        /// <summary>
        /// 进度条
        /// </summary>
        public Progressor _Progressor { set { _UserCreator._Progressor = value; } }

        /// <summary>
        /// 自定义图幅创建类
        /// </summary>
        private UserMapsheet _UserCreator = null;
        #endregion

        /// <summary>
        /// 初始化控件
        /// </summary>
        private void InitControl()
        {
            GridColumn chk = new GridColumn();
            chk.EditorType = typeof(GridCheckBoxXEditControl);
            chk.HeaderText = "";
            chk.Name = "colCheck";
            chk.Width = 40;
            chk.HeaderStyles.Default.Image = Properties.Resources._checked;
            chk.Tag = false;
            chk.ColumnSortMode = ColumnSortMode.None;
            _SuperGrid.PrimaryGrid.Columns.Add(chk);
            GridColumn chk1 = new GridColumn();
            chk1.EditorType = typeof(GridTextBoxXEditControl);
            chk1.HeaderText = "图号";
            chk1.Name = "colCode";
            chk1.Width = 100;
            chk1.ReadOnly = true;
            _SuperGrid.PrimaryGrid.Columns.Add(chk1);
            GridColumn chk2 = new GridColumn();
            chk2.EditorType = typeof(GridTextBoxXEditControl);
            chk2.HeaderText = "图名";
            chk2.Name = "colName";
            chk2.Width = 120;
            chk2.Visible = _HasName;
            _SuperGrid.PrimaryGrid.Columns.Add(chk2);
            chk2.ReadOnly = false;
            //_SuperGrid.PrimaryGrid.UseAlternateColumnStyle = true;
            _SuperGrid.PrimaryGrid.UseAlternateRowStyle = true;
            _SuperGrid.PrimaryGrid.ShowRowGridIndex = true;
            _SuperGrid.PrimaryGrid.SelectionGranularity = SelectionGranularity.Row;
            //_SuperGrid.PrimaryGrid.GroupHeaderHeight = 22;
            GridCheckBoxXEditControl colCheck = _SuperGrid.PrimaryGrid.Columns[0].EditControl as GridCheckBoxXEditControl;
            colCheck.CheckedChangedEx += colCheck_CheckedChangedEx;
            GridTextBoxXEditControl colName = _SuperGrid.PrimaryGrid.Columns["colName"].EditControl as GridTextBoxXEditControl;
            colName.TextChanged += colName_TextChanged;
            AllSheets = new List<Mapsheet>();
            _SuperGrid.ColumnHeaderClick += SuperGrid_ColumnHeaderClick;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void SuperGrid_ColumnHeaderClick(object sender, GridColumnHeaderClickEventArgs e)
        {
            //throw new NotImplementedException();
            if (e.GridColumn.Name.Equals("colCheck", StringComparison.CurrentCultureIgnoreCase))
            {
                if (e.GridColumn.Tag == null) return;
                bool chk = (bool)e.GridColumn.Tag;
                e.GridColumn.Tag = !chk;
                if (chk)
                {
                    e.GridColumn.HeaderStyles.Default.Image = Properties.Resources.nochecked;
                }
                else
                {
                    e.GridColumn.HeaderStyles.Default.Image = Properties.Resources._checked;
                }
                SetAllChecked(!chk);
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="chk"></param>
        private void SetAllChecked(bool chk)
        {
            foreach(GridRow row in _SuperGrid.PrimaryGrid.Rows)
            {
                row.Cells["colCheck"].Value = chk;
            }
        }

        /// <summary>
        /// 名称值改变
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void colName_TextChanged(object sender, EventArgs e)
        {
            GridTextBoxXEditControl ctl = sender as GridTextBoxXEditControl;
            GridRow r = ((IGridCellEditControl)ctl).EditorCell.GridRow;
            Mapsheet sheet = (Mapsheet)r.Tag;
            //sheet.Name = r.Cells[2].Value == null ? "" : r.Cells[2].Value.ToString();
            sheet.Name = ctl.EditorValue.ToString();
        }

        /// <summary>
        /// 选择状态改变
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void colCheck_CheckedChangedEx(object sender, CheckBoxXChangeEventArgs e)
        {
            if (e.EventSource == DevComponents.DotNetBar.eEventSource.Code) return;
            GridCheckBoxXEditControl ctl = sender as GridCheckBoxXEditControl;
            GridRow r = ((IGridCellEditControl)ctl).EditorCell.GridRow;
            Mapsheet sheet = (Mapsheet)r.Tag;
            sheet.Checked = ctl.Checked;

            #region 选择改变后画（删）Element对象
            if (_HookHelper == null || !(_HookHelper.Hook is IMapControl2)) return;
            IRgbColor pRgbColor = new RgbColor();
            pRgbColor.Red = 255;
            pRgbColor.Green = 0;
            pRgbColor.Blue = 0;
            if (sheet.Geometry == null || sheet.Geometry.IsEmpty) return;
            string name = string.Format("{0}{1}", _ElementName, sheet.Code); 
            if (sheet.Checked)
            {
                IElement ele = ElementHelper.AddPolygon(sheet.Geometry as IPolygon, _HookHelper.ActiveView, pRgbColor);
                IElementProperties ep = ele as IElementProperties;
                ep.Name = name;
                if (ele != null) Elements.Add(ele);
            }
            else
            {
                IElement ele = Elements.FirstOrDefault(t => (t as IElementProperties3).Name.Equals(name));
                IEnumElement em = _HookHelper.ActiveView.GraphicsContainer.LocateElementsByEnvelope(ele.Geometry.Envelope);
                if (em.Next() != null)
                    _HookHelper.ActiveView.GraphicsContainer.DeleteElement(ele);
                Elements.Remove(ele);
            }
            _HookHelper.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, null, _HookHelper.ActiveView.Extent);
            #endregion

        }

        /// <summary>
        /// 获取所选择的图幅对应的空间对象（合并为一个空间对象）
        /// </summary>
        /// <returns></returns>
        public IGeometry GetSelectGeometry()
        {
            List<Mapsheet> sheets = this.CheckedSheets;
            if (sheets == null || sheets.Count == 0) return null;
            var v = from p in sheets
                    select p.Geometry;
            return GeometryHelper.Union((List<IGeometry>)v.ToList());
        }

        /// <summary>
        /// 根据绘制的范围，选择所需的图幅
        /// </summary>
        /// <param name="geometry">已绘制的图形</param>
        /// <param name="shift">是否按下shift键</param>
        /// <param name="isStandard">是否为自定义图幅</param>
        public void SelectRegion(IGeometry geometry, int shift, bool isStandard = true)
        {
            if (AllSheets == null) AllSheets = new List<Mapsheet>();
            if (shift == 0)//未点Shift键
            {
                _SuperGrid.PrimaryGrid.Rows.Clear();
                if (AllSheets.Count > 0) AllSheets.Clear();
                AllSheets = new List<Mapsheet>();
                ClearElement();
            }
            if (geometry == null || geometry.IsEmpty) return;
            if (this.ScaleValue < 10) return;
            try
            {
                if (geometry is IPoint) geometry = (geometry as IPoint).ToCircle(2);
                else if (geometry is IEnvelope) geometry = ((IEnvelope)geometry).ToPolygon();
                if (geometry == null || geometry.IsEmpty) return;
                List<Mapsheet> sheets = null;
                if (!isStandard) sheets = _UserCreator.CreateMapsheet(geometry);
                else sheets = JHBHelper.GetSheetByGeometry(geometry, (int)ScaleValue);
                if (sheets == null || sheets.Count == 0) return;
                List<Mapsheet> tmplist = sheets;
                if (AllSheets.Count > 0) tmplist = sheets.Except(AllSheets).ToList();
                AllSheets.AddRange(tmplist);
                foreach (Mapsheet itm in tmplist)
                {
                    GridRow r = new GridRow(new object[] { true, itm.Code, "" });
                    _SuperGrid.PrimaryGrid.Rows.Add(r);
                    r.AllowEdit = true;
                    r.Tag = itm;
                }
                DrawElements(tmplist);
            }
            catch (System.Exception ex)
            {
                LogHelper.WriteErrLog(ex.Message);
            }
        }

        /// <summary>
        /// 根据图号，选择图幅
        /// </summary>
        /// <param name="codes">图号</param>
        public void SelectByCodes(List<string> codes)
        {
            if (AllSheets == null) AllSheets = new List<Mapsheet>();
            _SuperGrid.PrimaryGrid.Rows.Clear();
            if (AllSheets.Count > 0) AllSheets.Clear();
            ClearElement();
            if (codes == null || codes.Count==0) return;
            if (this.ScaleValue < 10) return;
            try
            {
                AllSheets = JHBHelper.GetSheetByCodes(codes, (int)ScaleValue);
                if (AllSheets == null || AllSheets.Count == 0) return;
                foreach (Mapsheet itm in AllSheets)
                {
                    GridRow r = new GridRow(new object[] { true, itm.Code, "" });
                    _SuperGrid.PrimaryGrid.Rows.Add(r);
                    r.AllowEdit = true;
                    r.Tag = itm;
                }
                DrawElements(AllSheets);
            }
            catch (System.Exception ex)
            {
                LogHelper.WriteErrLog(ex.Message);
            }
        }

        /// <summary>
        /// 将所选的图幅绘制到地图中
        /// </summary>
        /// <param name="sheets">新选择的图幅对象</param>
        public void DrawElements(List<Mapsheet> sheets)
        {
            if (!IsToMap) return;
            if (sheets == null || sheets.Count == 0) return;
            if (_HookHelper == null || !(_HookHelper.Hook is IMapControl2)) return;
            IRgbColor pRgbColor = new RgbColor();
            pRgbColor.Red = 255;
            pRgbColor.Green = 0;
            pRgbColor.Blue = 0;
            if (Elements == null) Elements = new List<IElement>();
            foreach (Mapsheet fu in sheets)
            {
                if (fu.Geometry == null || fu.Geometry.IsEmpty) continue;
                IElement ele = ElementHelper.AddPolygon(fu.Geometry as IPolygon, _HookHelper.ActiveView, pRgbColor);
                IElementProperties ep = ele as IElementProperties;
                //ep.Name = string.Format("{0}{1}", _ElementName, DateTime.Now.ToString("HHmmssttt"));
                ep.Name = string.Format("{0}{1}", _ElementName, fu.Code);
                if (ele != null) Elements.Add(ele);
            }
            _HookHelper.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, null, _HookHelper.ActiveView.Extent);
        }

        /// <summary>
        /// 清除地图中绘制的对象
        /// </summary>
        public void ClearElement()
        {
            if (Elements == null || Elements.Count == 0 || _HookHelper == null) return;
            IGraphicsContainer grp = _HookHelper.ActiveView.GraphicsContainer;
            grp.Reset();
            IElement ele = null;
            while ((ele = grp.Next()) != null)
            {
                IElementProperties ep = ele as IElementProperties;
                if (string.IsNullOrWhiteSpace(ep.Name)) continue;
                if (ep.Name.StartsWith(_ElementName)) grp.DeleteElement(ele);
            }
            _HookHelper.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics | esriViewDrawPhase.esriViewGraphicSelection, null, _HookHelper.ActiveView.Extent);
            Elements.Clear();
            Elements = new List<IElement>();
        }

    }
}
